package com.boy.commonutils.handler;

import com.boy.tool.utils.JwtUtils;
import com.boy.entity.Permission;
import com.boy.service.AccountService;
import com.boy.tool.annotate.Arbitrarily;
import com.boy.tool.enumClass.ExceptionCode;
import com.boy.tool.annotate.RequirePermissions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author whd
 * @date 2024/05/23 15:09:13
 */
@Component
@Slf4j
public class InterceptorHandler implements HandlerInterceptor {
    @Autowired
    private AccountService accountService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("Authorization");
        String method = request.getMethod();
        if ("OPTIONS".equals(method)) return true;
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method1 = handlerMethod.getMethod();
            RequirePermissions annotation = method1.getAnnotation(RequirePermissions.class);
            Arbitrarily arbitrarily = method1.getAnnotation(Arbitrarily.class);
            if (arbitrarily != null) {
                log.info("当前方法:{}，不需要token就可以访问", method1.getName());
                return true;
            }
            if (annotation == null) return true;
            if (!JwtUtils.checkToken(token)) throw new WhdException(ExceptionCode.TOKEN_IS_LOSE, "token失效");
            String id = JwtUtils.getMemberIdByJwtToken(token);
            List<String> collect = accountService.findPermission(id).stream().map(Permission::getNick).collect(Collectors.toList());
            if (collect.contains("All")) return true;
            String[] value = annotation.value();
            log.info("当前方法{}，需要权限{}", method1.getName(), Arrays.toString(value));
            List<String> requestPermission = Arrays.stream(value).collect(Collectors.toList());
            boolean b = new HashSet<>(collect).containsAll(requestPermission);
            if (!b) throw new WhdException(ExceptionCode.HADLE_EXCEPTION, "用户权限不足");
            return b;
        } else {
            return true;
        }
    }
}
